﻿#region File Description
//-----------------------------------------------------------------------------
// EnvironmentMappedMaterialProcessor.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System.IO;
using System.ComponentModel;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using System;
using System.Collections.Generic;
#endregion

namespace ContentPipeline
{
    /// <summary>
    /// Custom content pipeline processor derives from the built-in
    /// MaterialProcessor. This changes the material to use our custom
    /// environment mapping effect, and also builds the environment map
    /// texture in a special way.
    /// </summary>
    [ContentProcessor]
    public class UNMaterialProcessor : MaterialProcessor
    {
        [DisplayName("Custom Effect")]
        [Description("The custom effect applied to the model.")]
        public string CustomEffect
        {
            get { return customEffect; }
            set { customEffect = value; }
        }
        private string customEffect;

        /// <summary>
        /// Converts a material.
        /// </summary>
        public override MaterialContent Process(MaterialContent material,
                                                ContentProcessorContext context)
        {
            if (string.IsNullOrEmpty(customEffect))
                throw new ArgumentException("Custom Effect not set to an effect file");

            // Create a new effect material.
            EffectMaterialContent customMaterial = new EffectMaterialContent();

            // Point the new material at our custom effect file.
            string effectFile = Path.GetFullPath("effects/"+customEffect+".fx");
            customMaterial.Effect = new ExternalReference<EffectContent>(effectFile);

            if (material is BasicMaterialContent)
            {
                BasicMaterialContent basicMaterial = (BasicMaterialContent)material;
                if (basicMaterial.Texture != null)
                {
                    customMaterial.Textures.Add("Texture", basicMaterial.Texture);
                }
                customMaterial.OpaqueData.Add("DiffuseColor", basicMaterial.EmissiveColor);

                foreach (KeyValuePair<string, ExternalReference<TextureContent>> textureContent in material.Textures)
                {
                    if (textureContent.Key != "Texture")
                        customMaterial.Textures.Add(textureContent.Key, textureContent.Value);
                }

                // Loop over the opaque data in the current material adding them to 
                // the new material.
                foreach (KeyValuePair<string, Object> opaqueData in material.OpaqueData)
                {
                    if (opaqueData.Key != "DiffuseColor")
                        customMaterial.OpaqueData.Add(opaqueData.Key, opaqueData.Value);
                }

                /*
                string s = "";
                foreach(string st in basicMaterial.OpaqueData.Keys) {
                    s += st+" ";
                    s += basicMaterial.OpaqueData[st]+"\n";
                }
                
                throw new Exception(s);
                 * 
                 * DiffuseColor(0,0,0)
                 * EmissiveColor(0.47,0.32,0.19)
                 * Alpha 1
                 * Specular(0,0,0)
                 * VertexColorEnabled false
                 */
            }
            else if (material is EffectMaterialContent)
            {
                EffectMaterialContent effectMaterial = (EffectMaterialContent)material;

                // todo: put something interesting here if you want
                // or don't bother if you don't want
                // whatever really...
            }
            else
                throw new Exception("huh? this is very odd");
            // Chain to the base material processor.
            return base.Process(customMaterial, context);
        }
    }
}
